package com.sunyard.utils.tianan;

import cn.com.infosec.netsign.agent.RBCAgent;
import com.sunyard.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.validation.Valid;

/**
 * @description: TianAn 验签工具类
 * @author: DUANYUBIN
 * @create: 2021-03-11 20:56
 **/
@Slf4j
@Component
public class TianAnUtil {

    @Value("${tianan.ip}")
    private String ip;

    @Value("${tianan.password}")
    private String password;

    @Value("${tianan.point}")
    private String point;


    /**
     * 链接签名服务器
     */
    private RBCAgent getRbcAgent() throws IllegalArgumentException {
        RBCAgent rbcAgent = new RBCAgent();
        //建立到指定地址和端口的签名服务器的连接，使用指定的密码认证身份。
        rbcAgent.Connect(ip, point, password);
        //获取上次操作的返回码 1成功，其他均为失败
        int returnCode = rbcAgent.getReturnCode();
        if (returnCode != 1) {
            log.error("签名服务器链接失败");
            throw new IllegalArgumentException("签名服务器链接参数有误");
        }
        return rbcAgent;
    }

    /**
     * 断开签名服务器
     */
    private void closeRbcAgent(RBCAgent rbcAgent) {
        //关闭和签名服务器的连接。
        rbcAgent.Disconnect();
    }

    /**
     * 签名 2.2.1.4
     *
     * @Description: puglic String RawSign(String msg，String dn);
     */
    public String RawSign(@Valid TianAnSign tianAnSign) throws IllegalArgumentException {
        if (StringUtils.isBlank(tianAnSign.getSign())) {
            //签名内容不能为空
            log.error("签名内容不能为空");
            throw new IllegalArgumentException("签名内容不能为空");
        }
        RBCAgent rbcAgent = getRbcAgent();
        //使用指定的证书DN，从签名服务器获取对应的私钥证书，对指定的原始数据编制裸签名(PKCS#1)
        String s = rbcAgent.RawSign(tianAnSign.getSign(), tianAnSign.getDn());
        closeRbcAgent(rbcAgent);
        return s;
    }

    /**
     * 签名 2.2.1.4
     *
     * @Description: puglic String rawSign(byte[] msg，String dn);
     */
    public String rawSign(@Valid TianAnSign tianAnSign) throws Exception {
        if (tianAnSign.getMsg() == null || tianAnSign.getMsg().length == 0) {
            //签名内容不能为空
            log.error("签名内容不能为空");
            throw new IllegalArgumentException("签名内容不能为空");
        }
        RBCAgent rbcAgent = getRbcAgent();
        //使用指定的证书DN，从签名服务器获取对应的私钥证书，对指定的原始数据编制裸签名(PKCS#1)
        String s = rbcAgent.rawSign(tianAnSign.getMsg(), tianAnSign.getDn());
        closeRbcAgent(rbcAgent);
        return s;
    }

    /**
     * 验签 2.2.1.5
     *
     * @Description: public boolean rawVerify(byte[] msg，String signedData，String dn);
     */
    public boolean rawVerify(TianAnVerify tianAnVerify) throws Exception {
        if (tianAnVerify.getByteMsg() == null || tianAnVerify.getByteMsg().length == 0) {
            //签名原文不能为空
            log.error("签名原文不能为空");
            throw new IllegalArgumentException("签名原文不能为空");
        }
        RBCAgent rbcAgent = getRbcAgent();
        //使用指定的证书DN，或行号，从签名服务器获取对应的公钥证书，对指定的原始数据核验其裸签名。
        boolean b = rbcAgent.rawVerify(tianAnVerify.getByteMsg(), tianAnVerify.getSignData(), tianAnVerify.getDn());
        closeRbcAgent(rbcAgent);
        return b;
    }

    /**
     * 验签 2.2.1.5
     *
     * @Description: public boolean RawVerify(String msg，String signData，String dn);
     */
    public boolean RawVerify(TianAnVerify tianAnVerify) throws Exception {
        if (StringUtils.isBlank(tianAnVerify.getMsg())) {
            //签名原文不能为空
            log.error("签名原文不能为空");
            throw new IllegalArgumentException("签名原文不能为空");
        }
        RBCAgent rbcAgent = getRbcAgent();
        //使用指定的证书DN，或行号，从签名服务器获取对应的公钥证书，对指定的原始数据核验其裸签名
        boolean b = rbcAgent.RawVerify(tianAnVerify.getMsg(), tianAnVerify.getSignData(), tianAnVerify.getDn());
        closeRbcAgent(rbcAgent);
        return b;
    }
}
